home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / news / nntp / nntp.1.5.11 / server / timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-27  |  3.8 KB  |  171 lines

  1. /*
  2.  * Machinery to run routines off timers.
  3.  */
  4. #include "common.h"
  5.  
  6. #ifdef TIMERS
  7. #ifndef lint
  8. static char rcsid[] =
  9.     "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP with TIMERS)";
  10. #endif
  11. #else
  12. #ifndef lint
  13. static char rcsid[] =
  14.     "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP without TIMERS)";
  15. #endif
  16. #endif
  17.  
  18. #ifdef TIMERS
  19. #include <sys/time.h>
  20. #include "timer.h"
  21. #ifndef USG
  22. #ifndef FD_SETSIZE
  23. /* Forward compatability */
  24. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
  25. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
  26. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
  27. #define FD_ZERO(p)      ((p)->fds_bits[0] = 0)
  28. #endif
  29. #endif
  30. /* non-portable */
  31. #define BUFFERED_DATA(f) ((f)->_cnt > 0)
  32.  
  33. static long lastsecs;
  34.  
  35. /*
  36.  * Should be called before first call to timer_sleep()
  37.  */
  38. void
  39. timer_init(timers, ntimer)
  40.     register struct timer *timers;
  41.     register int ntimer;
  42. {
  43.     register int i;
  44.     register struct timer *tp;
  45.  
  46. #ifdef SYSLOG
  47.     if (ntimer <= 0)
  48.         syslog(LOG_ERR,
  49.             "timer_init(): configuration error, %d timers\n", ntimer);
  50. #endif
  51.  
  52.     /* Reset all timers */
  53.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  54.         tp->left = tp->seconds;
  55.  
  56.     /* Start clock */
  57.     lastsecs = time((long *)0);
  58. }
  59.  
  60. /*
  61.  * Sleep until input or next timer needs to be run and then run any
  62.  * expired timers. Returns true if input is available to be read.
  63.  */
  64. int
  65. timer_sleep(timers, ntimer)
  66.     register struct timer *timers;
  67.     register int ntimer;
  68. {
  69.     register int i, n;
  70.     register struct timer *tp;
  71.     register long secs;
  72. #ifdef USG
  73.     long timeout;
  74.     long readfds;
  75. #else
  76.     register struct timeval *timeoutp;
  77.     struct timeval timeout;
  78.     fd_set readfds;
  79. #endif
  80.  
  81.     /* No need to do the select if there are characters in the buffer */
  82.     if (BUFFERED_DATA(stdin))
  83.         return(1);
  84.  
  85.     /* Length of next timeout is minimum of all "timers" */
  86. #ifdef USG
  87.     timeout = -1;
  88.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  89.         if (tp->left >= 0 &&
  90.             (tp->left < timeout || timeout < 0))
  91.             timeout = tp->left;
  92.  
  93.     /* If active timeouts (this can easily happen), block until input */
  94.     if (timeout < 0)
  95.         timeout = 0;
  96. #ifdef EXCELAN
  97.     readfds = 1<<(fileno(stdin));
  98.     timeout = timeout * 1000;     /* timeout needs to be in milliseconds */
  99. #endif /* EXCELAN */
  100. #else
  101.     timeout.tv_sec = -1;
  102.     timeout.tv_usec = 0;
  103.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  104.         if (tp->left >= 0 &&
  105.             (tp->left < timeout.tv_sec || timeout.tv_sec < 0))
  106.             timeout.tv_sec = tp->left;
  107.  
  108.     /* If active timeouts (this can easily happen), block until input */
  109.     if (timeout.tv_sec < 0)
  110.         timeoutp = 0;
  111.     else
  112.         timeoutp = &timeout;
  113.  
  114.     /* Do select */
  115.     FD_ZERO(&readfds);
  116.     FD_SET(fileno(stdin), &readfds);
  117. #endif /* !USG */
  118.     errno = 0;
  119. #ifdef EXCELAN
  120.     n = select(fileno(stdin) + 1, &readfds, (long*)0, timeout);
  121. #else
  122.     n = select(fileno(stdin) + 1,
  123.         &readfds, (fd_set*)0, (fd_set*)0, timeoutp);
  124. #endif
  125.     /* "Interrupted system call" isn't a real error */
  126.     if (n < 0 && errno != EINTR) {
  127. #ifdef SYSLOG
  128.         syslog(LOG_ERR, "%s read select: %m", hostname);
  129. #endif
  130.         exit(1);
  131.     }
  132.  
  133.     /* Calculate off seconds since last time */
  134.     secs = time((long *)0) - lastsecs;
  135.     if (secs < 0)
  136.         secs = 0;
  137.  
  138.     /* Subtract time from "timers" that have time remaining */
  139.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  140.         if (tp->left > 0 && (tp->left -= secs) < 0)
  141.             tp->left = 0;
  142.  
  143.     /* Update lastsecs */
  144.     lastsecs += secs;
  145.  
  146.     /* If we have input, reset clock on guys that like it that way */
  147.     if (n > 0)
  148.         for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  149.             if (tp->resetoninput)
  150.                 tp->left = tp->seconds;
  151.  
  152.     /* Process "timers" that have timed out */
  153.     for (i = ntimer, tp = timers; i > 0; --i, ++tp) {
  154.         if (tp->left == 0) {
  155.             (tp->subr)();
  156.             /* resetoninput guys only get "reset on input" */
  157.             if (tp->resetoninput)
  158.                 tp->left = -1;
  159.             else
  160.                 tp->left = tp->seconds;
  161.         }
  162.     }
  163.  
  164.     /* Indicate no input */
  165.     if (n <= 0)
  166.         return(0);
  167.     return(1);
  168.     
  169. }
  170. #endif
  171.